﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Battle.Engine.LogicModel;

namespace Battle.Engine.AI
{
    public class EnginePlaybackAI : EngineAI 
    {

        Queue<EnginePlaybackAIMsg> aiMsgQueue = new Queue<EnginePlaybackAIMsg>();
        EnginePlaybackAIMsg curMsg = null;

        List<FSkill> dealingSkills = new List<FSkill>();

        ProtoBuf.Message.BattleOperate optRecord = null;
        public void SetOperateRecord(ProtoBuf.Message.BattleOperate opt)
        {
            optRecord = opt;
        }

        public override void Run()
        {
            if (isRunning)
            {
                return;
            }

            isRunning = true;
            aiMsgQueue.Clear();
            curMsg = null;

            if (data.curRoundCamp == CampType.ATTACK && optRecord.attackerTransOpt != null && optRecord.attackerTransOpt.roundNum == data.roundNum)
            {
                List<string> actorUids = new List<string>();
                foreach (var uid in optRecord.attackerTransOpt.actorUids)
                {
                    actorUids.Add("0_" + uid);
                }
                engine.DoTrans(actorUids, optRecord.attackerTransOpt.fpids);
            }
            else if (data.curRoundCamp == CampType.DEFENCE && optRecord.defenderTransOpt != null && optRecord.defenderTransOpt.roundNum == data.roundNum)
            {
                engine.DoTrans(optRecord.defenderTransOpt.actorUids, optRecord.defenderTransOpt.fpids);
            }

            foreach (var opt in optRecord.skillOpts)
            {
                if (opt.roundNum == data.roundNum)
                {
                    var actor = player.GetActorByUID(opt.camp.ToString() + "_" + opt.actorUid);
                    if (actor == null)
                    {
                        Debug.LogError("Actor " + opt.actorUid + " not exist!!");
                        continue;
                    }
                    else
                    {
                        EnginePlaybackAIMsg msg = new EnginePlaybackAIMsg(actor, opt.skillIndex, opt.roundTime);
                        aiMsgQueue.Enqueue(msg);
                    }
                }
            }
        }

        public override void Update(double deltaTime)
        {
            if (isRunning == false)
                return;

            for (int i = 0; i < dealingSkills.Count; ++i)
            {
                if (dealingSkills[i].state == FSkillState.FINISH)
                {
                    dealingSkills.RemoveAt(i);
                    i--;
                }
            }

            if (curMsg == null)
            {
                if (aiMsgQueue.Count > 0)
                {
                    curMsg = aiMsgQueue.Dequeue();
                }
            }

            if (curMsg != null)
            {
                if (data.roundTime >= curMsg.time)
                {
                    engine.DoSkill(curMsg.actor.player.camp, curMsg.actor.uniqueId, curMsg.skill.index);
                    dealingSkills.Add(curMsg.skill);
                    curMsg = null;
                }
            }

            if (curMsg == null && aiMsgQueue.Count == 0 && dealingSkills.Count == 0)
            {
                if (data.compute.IsSkipping())
                {
                    if (callback != null)
                    {
                        callback.FinishRound();
                    }
                }
                else
                {
                    if (callback != null)
                    {
                        callback.HaventActiveNormalSkill();
                    }

                }

            }

        }

    }
}
